<script>
  import $ from '../dfish.js'
  import {
    h
  } from 'vue'
  import Text from './Text.vue'
  import Dialog from './Dialog.vue'
  import Calendar from './Calendar.vue'

  export default {
    name: 'w-datepicker',
    mixins: [Text],
    inject: ['provideRangeParent'],
    props: ['noButton', 'multiple', 'format', 'compare', 'minValue', 'maxValue', 'validateDefault'],
    data() {
      return {
        showDrop: false,
        currentDate: null,
        placeholder_type: 'placeholder_select',
      }
    },
    methods: {
      x_default() {
        return {
          format: 'yyyy-MM-dd',
          inputWidth: 180
        }
      },
      drop() {
        if ($.br.mobile) {
          $.dateSheet({
            value: this.x.modelValue,
            format: this.x.format,
            ...this.getPeriod(),
            success: this.calendarCallback,
          })
        } else {
          this.showDrop = true
        }
      },
      calendarCallback(val) {
        this.val(val)
        this.showDrop = false
        this.currentDate = null
        if (!$.br.mobile)
          this.focus()
      },
      getPeriod() {
        let minValue = this.x.minValue
        let maxValue = this.x.maxValue
        let p = this.provideRangeParent && this.provideRangeParent.forms()
        if (p) {
          if (p[0] == this) {
            let end = p[1].formVal()
            if (end != null && (maxValue == null || maxValue > end)) maxValue = end
          } else if (p[1] == this) {
            let begin = p[0].formVal()
            if (begin != null && (minValue == null || minValue < begin)) minValue = begin
          }
        }
        return {
          minValue,
          maxValue
        }
      },
      html_button() {
        let r = []
        if (!this.x.noButton) r.push(h('button', {
          class: 'w-input-bbr f-i f-i-date',
          disabled: this.x.disabled,
        }))
        if (this.showDrop) {
          r.push(h(Dialog, {
            ownproperty: true,
            class: 'f-dfish-dialog w-calendar-dialog',
            width: 260,
            context: this,
            autoHide: true,
            snap: {
              target: () => this.snapElem(),
              position: 'v',
              indent: 1
            },
            on: {
              close: () => {
                this.showDrop = false, this.currentDate = null
              }
            }
          }, {
            default: () => h(Calendar, {
              pad: true,
              current: this.currentDate || this.x.modelValue || '',
              value: this.x.modelValue,
              format: this.x.format,
              ...this.getPeriod(),
              success: this.calendarCallback,
              on: {
                'click:item': (e, item) => this.currentDate = item.value,
              }
            })
          }))
        }
        return r
      },
    },
    computed: {
      validHooks() {
        return {
          ...this.pubValidHooks,
          minValue: (v, r, q) => {
            if (v && $.dateParse(v, this.x.format) < $.dateParse(r, this.x.format))
              return this.formErr(q)
          },
          maxValue: (v, r, q) => {
            if (v && $.dateParse(v, this.x.format) > $.dateParse(r, this.x.format))
              return this.formErr(q)
          },
          compare: (v, r, q) => {
            if (v && r && r.target && r.mode && this.ownerView) {
              let t = this.ownerView.f(r.target)
              let tv = t && t.formVal()
              if (tv) {
                let d = $.dateParse(v, this.x.format)
                let td = $.dateParse(tv, this.x.format)
                if(!$.eval('d' + r.mode + 'td', {d, td}))
                  return this.formErr(q, [this.getLabelText(), r.mode, t.getLabelText()])
              }
            }
          },
          validateDefault: (v, r, q) => {
            if (this.x.multiple)
              return;
            if (v) {
              let c = v
              let d = $.dateParse(c, this.x.format)
              let y = d.getFullYear()
              let m = 9999
              let n = 1000
              if (y > m || y < n)
                return this.formErr({type: 'time_exceed'}, [n, m]);
              if (c != $.dateFormat(d, this.x.format)) {
                return this.formErr({type: 'time_format'}, [$.dateFormat(d, this.x.format)]);
              }
            }
            if (this.defaultRuleValue('beforeNow') && v && v > $.dateFormat(new Date(), this.x.format))
              return this.formErr({type: 'beforeNow'}, [this.x.beforeNow]);
            if (this.defaultRuleValue('afterNow') && v && v < $.dateFormat(new Date(), this.x.format))
              return this.formErr({type: 'afterNow'}, [this.x.afterNow]);
            if (this.provideRangeParent)
              return this.provideRangeParent.getRangeError()
          }
        }
      },
      input_prop() {
        return $.br.mobile && {
          readonly: true
        }
      },
      main_prop() {
        return {
          onclick: this.isNormal && this.drop
        }
      }
    }
  }
</script>
